// 网页HTML源码
const char* htmlPage = R"rawliteral(<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
  <title>遥控汽车控制</title>
  <style>
    * {
      box-sizing: border-box;
      margin: 0;
      padding: 0;
      touch-action: none;
    }
    
    body {
      font-family: "Microsoft YaHei", "微软雅黑", Arial, sans-serif;
      background: #f0f0f0;
      color: #333;
      height: 100vh;
      flex-direction: column;
      align-items: center;
      justify-content: space-between;
      padding: 5px;
      overflow: hidden;
    }
    
    .header {
      text-align: center;
      padding: 2px 0;
      color: #2c3e50;
      font-size: 18px;
      font-weight: bold;
    }    
    .footer {
      margin-top: auto;
      padding: 10px;
      font-size: 0.8rem;
      color: #7f8c8d;
    }
    .control-group {
      background: white;
      padding: 5px;
      margin-Top: 5px;
      margin-bottom: 5px;
      border-radius: 5px;
      box-shadow: 0 2px 8px rgba(0,0,0,0.1);      
      width: 100%;
    }
    .slider-container {
      margin: 5px 0;
    }
    .joystick-container {
      position: relative;
      width: 220px;
      height: 220px;
      margin: 5px auto;
      background: #e0e0e0;
      border-radius: 5px;
      box-shadow: inset 0 0 20px rgba(0,0,0,0.2);
      touch-action: none;
    }
    
    .joystick {
      position: absolute;
      width: 40px;
      height: 40px;
      background: #3498db;
      border-radius: 50%;
      top: 50px;
      left: 50px;
      box-shadow: 0 4px 10px rgba(0,0,0,0.3);
      cursor: move;
      touch-action: none;
      z-index: 10;
    }
    
    .center-line {
      position: absolute;
      background: rgba(0,0,0,0.1);
    }
    
    .horizontal-line {
      width: 100%;
      height: 1px;
      top: 50%;
    }
    
    .vertical-line {
      width: 1px;
      height: 100%;
      left: 50%;
    }
    
    .status-panel {
      width: 100%;
      background: white;
      border-radius: 5px;
      padding: 5px;
      box-shadow: 0 4px 12px rgba(0,0,0,0.1);
      margin-bottom: 5px;
    }
    
    .status-row {
      display: flex;
      justify-content: space-between;
      margin: 5px 0;
      font-size: 12px;
    }
    
    .status-label {
      color: #7f8c8d;
    }
    
    .status-value {
      font-weight: bold;
    }
    
    .direction-value {
      color: #3498db;
    }
    
    .speed-value {
      color: #e74c3c;
    }
    
    .direction-indicator {
      display: inline-block;
      width: 20px;
      height: 20px;
      border-radius: 50%;
      margin-left: 10px;
      vertical-align: middle;
    }
    
    .forward { background-color: #27ae60; }
    .backward { background-color: #e74c3c; }
    .stop { background-color: #7f8c8d; }
    
    .buttons {
      display: flex;
      justify-content: space-between;
      width: 100%;
      margin-top: 5px;
    }
    
    button {
      background: #3498db;
      color: white;
      border: none;
      padding: 5px 0;
      border-radius: 5px;
      font-size: 16px;
      cursor: pointer;
      flex: 1;
      margin: 0 5px;
      transition: all 0.2s;
    }
    
    button:active {
      background: #2980b9;
      transform: scale(0.98);
    }
    
    .emergency-stop {
      background: #e74c3c;
      margin-top: 5px;
      width: 100%;
	  max-height: 40px;
    }
    
    .emergency-stop:active {
      background: #c0392b;
    }

  </style>
</head>
<body>
  <div class="header">ESP32 WIFI 智能车遥控器</div>
  
  <div class="joystick-container">
    <div class="center-line horizontal-line"></div>
    <div class="center-line vertical-line"></div>
    <div class="joystick" id="joystick"></div>
  </div>
  
  <div class="status-panel">
    <div class="status-row">
      <span class="status-label">方向角度:</span>
      <span class="status-value direction-value" id="angleValue">90°</span>
    </div>
    <div class="status-row">
      <span class="status-label">电机状态:</span>
      <span class="status-value" id="motorState">停止</span>
      <span id="motorDirection" class="direction-indicator stop"></span>
    </div>
    <div class="status-row">
      <span class="status-label">电机速度:</span>
      <span class="status-value speed-value" id="speedValue">0%</span>
    </div>
  </div>
  <div class="buttons">
    <button onclick="setMotor(150)">半速前进</button>
    <button onclick="setMotor(50)">半速后退</button>
  </div>
  <div class="footer">
	   DIY模块地址: https://shop64022682.taobao.com/
	</div>
  
  <button class="emergency-stop" onclick="emergencyStop()">紧急停止/回正</button>
    <div class="control-group">
      <div class="slider-container">
      方向居中微调（0-200）
        <input type="range" min="0" max="200" value="0" class="slider" id="sg90OffsetSlider">
      </div>
      当前值: <span id="currentOffset">0</span>
    </div>
  
  <div class="footer">
	   DIY模块地址: https://shop64022682.taobao.com/
	</div>
  <script>
    // 摇杆控制
    const joystick = document.getElementById('joystick');
    const angleValue = document.getElementById('angleValue');
    const motorState = document.getElementById('motorState');
    const motorDirection = document.getElementById('motorDirection');
    const speedValue = document.getElementById('speedValue');
    
    let isDragging = false;
    const containerSize = 220; // 容器大小
    const joystickSize = 20; // 摇杆半径
    let centerPos = containerSize / 2;
    let currentAngle = 90;
    let currentSpeed = 100; // 100表示停止
    
    // 控制发送频率
    let lastSendTime = 0;
    const sendInterval = 100; // 100ms发送间隔
    
    // 初始化摇杆位置
    joystick.style.left = (centerPos - joystick.offsetWidth/2) + 'px';
    joystick.style.top = (centerPos - joystick.offsetHeight/2) + 'px';
    
    // 触摸/鼠标事件处理
    joystick.addEventListener('mousedown', startDrag);
    joystick.addEventListener('touchstart', startDrag);
    
    document.addEventListener('mousemove', drag);
    document.addEventListener('touchmove', drag);
    
    document.addEventListener('mouseup', endDrag);
    document.addEventListener('touchend', endDrag);

    
    function startDrag(e) {
      isDragging = true;
      e.preventDefault();
    }
    
    function drag(e) {
      if (!isDragging) return;
      e.preventDefault();
      
      let clientX, clientY;
      
      if (e.type === 'touchmove') {
        clientX = e.touches[0].clientX;
        clientY = e.touches[0].clientY;
      } else {
        clientX = e.clientX;
        clientY = e.clientY;
      }
      
      const containerRect = document.querySelector('.joystick-container').getBoundingClientRect();
      const containerX = containerRect.left;
      const containerY = containerRect.top;
      
      // 计算相对于容器中心的偏移量
      let deltaX = clientX - containerX - centerPos;
      let deltaY = clientY - containerY - centerPos;
      
      // 方形边界限制 - 增大控制范围到容器边缘
      const maxDelta = centerPos - joystick.offsetWidth/2;
      deltaX = Math.max(-maxDelta, Math.min(maxDelta, deltaX));
      deltaY = Math.max(-maxDelta, Math.min(maxDelta, deltaY));
      
      // 更新摇杆位置
      joystick.style.left = (centerPos + deltaX - joystick.offsetWidth/2) + 'px';
      joystick.style.top = (centerPos + deltaY - joystick.offsetHeight/2) + 'px';
      
      // 计算方向角度 (横向控制: 左115°-中90°-右65°)
      let angle = 90 - (deltaX / maxDelta) * 25; // 90±25°
      angle = Math.max(65, Math.min(115, Math.round(angle))); // 限制在65-115度之间
      
      // 计算速度 (纵向控制: 上200-中100-下0)
      let speedPercent = (deltaY / maxDelta) * 100; // -100%到+100%
      let motorValue;
      if (speedPercent < 0) { // 向上是前进
        motorValue = 100 + Math.abs(speedPercent);
      } else { // 向下是后退
        motorValue = 100 - speedPercent;
      }
      motorValue = Math.max(0, Math.min(200, Math.round(motorValue))); // 限制在0-200
      
      // 更新显示
      updateDisplay(angle, motorValue);
      
      // 控制发送频率
      const now = Date.now();
      if (now - lastSendTime >= sendInterval) {
        // 发送控制命令
        sendControl("servo", angle);
        sendControl("motor", motorValue);
        lastSendTime = now;
      }
    }
    
    function endDrag() {
      if (!isDragging) return;
      isDragging = false;
      
      // 摇杆回中
      joystick.style.left = (centerPos - joystick.offsetWidth/2) + 'px';
      joystick.style.top = (centerPos - joystick.offsetHeight/2) + 'px';
      
      // 方向回中(90°)，速度停止(100)
      updateDisplay(90, 100);
      
      // 发送停止命令
      sendControl("servo", 90);
      sendControl("motor", 100);
    }
    
    function updateDisplay(angle, motorValue) {
      // 更新角度显示
      currentAngle = angle;
      angleValue.textContent = currentAngle + '°';
      
      // 更新电机状态显示
      currentSpeed = motorValue;
      if(motorValue > 100) {
        const speed = Math.round(motorValue - 100);
        motorState.textContent = "前进";
        motorDirection.className = "direction-indicator forward";
        speedValue.textContent = speed + "%";
      } else if(motorValue < 100) {
        const speed = Math.round(100 - motorValue);
        motorState.textContent = "后退";
        motorDirection.className = "direction-indicator backward";
        speedValue.textContent = speed + "%";
      } else {
        motorState.textContent = "停止";
        motorDirection.className = "direction-indicator stop";
        speedValue.textContent = "0%";
      }
    }
    
    // 电机控制按钮
    function setMotor(value) {
      updateDisplay(currentAngle, value);
      sendControl("motor", value);
    }
    
    // 紧急停止
    function emergencyStop() {
      updateDisplay(90, 100);
      sendControl("servo", 90);
      sendControl("motor", 100);
      
      // 摇杆回中
      joystick.style.left = (centerPos - joystick.offsetWidth/2) + 'px';
      joystick.style.top = (centerPos - joystick.offsetHeight/2) + 'px';
    }
    
    // 发送控制命令
    function sendControl(type, value) {
      var xhr = new XMLHttpRequest();
      xhr.open("GET", "/control?type=" + type + "&value=" + value, true);
      xhr.send();
    }
    
    // 更新位置显示
    function updateSg90Offset(offsetValue) {
      document.getElementById('currentOffset').textContent = offsetValue;
      document.getElementById('sg90OffsetSlider').value = offsetValue;
    }
        
    // 事件监听
    document.addEventListener('DOMContentLoaded', function() {
      // 滑块位置控制
      var offsetValueSlider = document.getElementById('sg90OffsetSlider');
      offsetValueSlider.addEventListener('input', function() {
        sendControl('sg90Offset', this.value);
      });
            // 初始状态更新
      function updateStatus() {
        fetch('/status')
          .then(response => response.json())
          .then(data => {
            updateSg90Offset(data.sg90Offset.toFixed(1));
          });
      }
      
      // 每秒更新一次状态
      setInterval(updateStatus, 1000);
      updateStatus(); // 初始更新
    });
  </script>
</body>
</html>
)rawliteral";